import { ref, onUnmounted } from 'vue';
import type { RealtimeData, AlarmData, PositionData } from '@/types/chart';
import { WEBSOCKET_CONFIG, CHART_CONFIG } from '@/config/constants';

/**
 * WebSocket连接管理组合式函数
 * 管理多个WebSocket连接：图表数据、报警数据、位置信息
 * 提供连接状态监控和数据更新功能
 */
export function useWebSocket() {
  const isConnected = ref(false);
  const connectionStatus = ref<{
    echarts: boolean;
    police: boolean;
    position: boolean;
  }>({
    echarts: false,
    police: false,
    position: false
  });

  /**
   * 生成200个基础测试数据点
   * 用于初始化图表显示和测试
   */
  const generateBaseData = (): RealtimeData => {
    const baseCount = CHART_CONFIG.BASE_DATA_COUNT;
    return {
      X: Array.from({ length: baseCount }, (_, i) => (i * 0.1).toFixed(1)),
      X1: Array.from({ length: baseCount }, (_, i) => -100 + Math.sin(i * 0.1) * 80 + Math.random() * 40 - 20),
      X2: Array.from({ length: baseCount }, (_, i) => 150 + Math.sin(i * 0.15) * 80 + Math.random() * 30 - 15),
      Y1: Array.from({ length: baseCount }, (_, i) => 5800 + Math.cos(i * 0.1) * 200 + Math.random() * 100 - 50),
      Y2: Array.from({ length: baseCount }, (_, i) => 5900 + Math.cos(i * 0.12) * 180 + Math.random() * 90 - 45),
      SpeedList: Array.from({ length: baseCount }, (_, i) => 80 + Math.sin(i * 0.05) * 30 + Math.random() * 20 - 10),
      MoHaoList1: Array.from({ length: baseCount }, (_, i) => 8 + Math.sin(i * 0.3) * 4 + Math.random() * 2),
      MoHaoList2: Array.from({ length: baseCount }, (_, i) => 10 + Math.cos(i * 0.25) * 3 + Math.random() * 1.5),
      WearList: Array.from({ length: baseCount }, (_, i) => 20 + Math.sin(i * 0.2) * 15 + Math.random() * 10 - 5),
      fVot: Array.from({ length: baseCount }, (_, i) => 27 + Math.sin(i * 0.05) * 2 + Math.random() * 1),
      fPressList1: Array.from({ length: baseCount }, (_, i) => 150 + Math.sin(i * 0.1) * 50 + Math.random() * 30),
      fPressList2: Array.from({ length: baseCount }, (_, i) => 160 + Math.cos(i * 0.12) * 45 + Math.random() * 25),
      fVibrationList1: Array.from({ length: baseCount }, (_, i) => 25 + Math.sin(i * 0.2) * 15 + Math.random() * 10),
      fVibrationList2: Array.from({ length: baseCount }, (_, i) => 28 + Math.cos(i * 0.18) * 12 + Math.random() * 8)
    };
  };

  // 响应式数据
  const chartData = ref<RealtimeData>(generateBaseData());
  const alarmData = ref<AlarmData[]>([]);
  const positionData = ref<PositionData>({});

  // WebSocket连接实例
  let echartsSocket: WebSocket | null = null;
  let policeSocket: WebSocket | null = null;
  let positionSocket: WebSocket | null = null;

  // 重连配置
  const reconnectConfig = {
    maxAttempts: WEBSOCKET_CONFIG.RECONNECT.MAX_ATTEMPTS,
    delay: WEBSOCKET_CONFIG.RECONNECT.DELAY,
    currentAttempts: {
      echarts: 0,
      police: 0,
      position: 0
    }
  };

  /**
   * 创建单个WebSocket连接的通用函数
   * @param url WebSocket URL
   * @param type 连接类型
   * @param onMessage 消息处理回调
   * @returns WebSocket实例
   */
  const createWebSocket = (
    url: string,
    type: 'echarts' | 'police' | 'position',
    onMessage: (event: MessageEvent) => void
  ): WebSocket | null => {
    try {
      const socket = new WebSocket(url);

      socket.onopen = () => {
        console.log(`${type} WebSocket已连接: ${url}`);
        connectionStatus.value[type] = true;
        reconnectConfig.currentAttempts[type] = 0;
        updateOverallConnectionStatus();
      };

      socket.onmessage = onMessage;

      socket.onclose = (event) => {
        console.log(`${type} WebSocket连接已关闭:`, event.code, event.reason);
        connectionStatus.value[type] = false;
        updateOverallConnectionStatus();

        // 自动重连逻辑
        if (reconnectConfig.currentAttempts[type] < reconnectConfig.maxAttempts) {
          reconnectConfig.currentAttempts[type]++;
          console.log(`尝试重连 ${type} WebSocket (${reconnectConfig.currentAttempts[type]}/${reconnectConfig.maxAttempts})`);
          setTimeout(() => {
            reconnectSingleSocket(type);
          }, reconnectConfig.delay);
        } else {
          console.error(`${type} WebSocket重连失败，已达到最大重试次数`);
        }
      };

      socket.onerror = (error) => {
        console.error(`${type} WebSocket错误:`, error);
        connectionStatus.value[type] = false;
        updateOverallConnectionStatus();
      };

      return socket;
    } catch (error) {
      console.error(`创建 ${type} WebSocket失败:`, error);
      return null;
    }
  };

  /**
   * 更新总体连接状态
   */
  const updateOverallConnectionStatus = () => {
    isConnected.value = connectionStatus.value.echarts ||
                       connectionStatus.value.police ||
                       connectionStatus.value.position;
  };

  /**
   * 重连单个WebSocket
   * @param type 连接类型
   */
  const reconnectSingleSocket = (type: 'echarts' | 'police' | 'position') => {
    switch (type) {
      case 'echarts':
        if (!echartsSocket || echartsSocket.readyState === WebSocket.CLOSED) {
          echartsSocket = createWebSocket(
            `${WEBSOCKET_CONFIG.BASE_URL}${WEBSOCKET_CONFIG.ENDPOINTS.ECHARTS}`,
            'echarts',
            handleEchartsMessage
          );
        }
        break;
      case 'police':
        if (!policeSocket || policeSocket.readyState === WebSocket.CLOSED) {
          policeSocket = createWebSocket(
            `${WEBSOCKET_CONFIG.BASE_URL}${WEBSOCKET_CONFIG.ENDPOINTS.POLICE}`,
            'police',
            handlePoliceMessage
          );
        }
        break;
      case 'position':
        if (!positionSocket || positionSocket.readyState === WebSocket.CLOSED) {
          positionSocket = createWebSocket(
            `${WEBSOCKET_CONFIG.BASE_URL}${WEBSOCKET_CONFIG.ENDPOINTS.POSITION}`,
            'position',
            handlePositionMessage
          );
        }
        break;
    }
  };

  /**
   * 处理图表数据消息
   */
  const handleEchartsMessage = (event: MessageEvent) => {
    try {
      const data = JSON.parse(event.data) as RealtimeData;
      updateChartData(data);
    } catch (error) {
      console.error('解析图表数据失败:', error);
    }
  };

  /**
   * 处理报警数据消息
   */
  const handlePoliceMessage = (event: MessageEvent) => {
    try {
      const data = JSON.parse(event.data) as AlarmData[];
      alarmData.value = data;
    } catch (error) {
      console.error('解析报警数据失败:', error);
    }
  };

  /**
   * 处理位置信息消息
   */
  const handlePositionMessage = (event: MessageEvent) => {
    try {
      const data = JSON.parse(event.data) as PositionData;
      if (positionData.value.POL !== data.POL) {
        positionData.value = data;
      }
    } catch (error) {
      console.error('解析位置数据失败:', error);
    }
  };

  /**
   * 连接所有WebSocket
   */
  const connectWebSockets = () => {
    // 重置重连计数器
    Object.keys(reconnectConfig.currentAttempts).forEach(key => {
      reconnectConfig.currentAttempts[key as keyof typeof reconnectConfig.currentAttempts] = 0;
    });

    // 创建各个WebSocket连接
    echartsSocket = createWebSocket(
      `${WEBSOCKET_CONFIG.BASE_URL}${WEBSOCKET_CONFIG.ENDPOINTS.ECHARTS}`,
      'echarts',
      handleEchartsMessage
    );
    policeSocket = createWebSocket(
      `${WEBSOCKET_CONFIG.BASE_URL}${WEBSOCKET_CONFIG.ENDPOINTS.POLICE}`,
      'police',
      handlePoliceMessage
    );
    positionSocket = createWebSocket(
      `${WEBSOCKET_CONFIG.BASE_URL}${WEBSOCKET_CONFIG.ENDPOINTS.POSITION}`,
      'position',
      handlePositionMessage
    );
  };

  /**
   * 断开所有WebSocket连接
   */
  const disconnectWebSockets = () => {
    const closeSocket = (socket: WebSocket | null, type: string) => {
      if (socket && socket.readyState === WebSocket.OPEN) {
        socket.close(1000, '用户主动断开连接');
        console.log(`${type} WebSocket已断开`);
      }
    };

    closeSocket(echartsSocket, '图表');
    closeSocket(policeSocket, '报警');
    closeSocket(positionSocket, '位置');

    // 清空引用
    echartsSocket = null;
    policeSocket = null;
    positionSocket = null;

    // 重置连接状态
    connectionStatus.value = {
      echarts: false,
      police: false,
      position: false
    };
    isConnected.value = false;
  };

  /**
   * 数据范围过滤器 - 超出范围的数据设为null
   * @param value 原始数值
   * @param min 最小值
   * @param max 最大值
   * @returns 过滤后的数值或null
   */
  const filterDataInRange = (value: number, min: number, max: number): number | null => {
    return (value >= min && value <= max) ? value : null;
  };

  /**
   * 处理数组数据范围过滤
   * @param data 原始数据数组
   * @param min 最小值
   * @param max 最大值
   * @returns 过滤后的数据数组
   */
  const processDataRange = (data: number[], min: number, max: number): (number | null)[] => {
    return data.map(value => filterDataInRange(value, min, max));
  };

  /**
   * 按WebSocket接收频率直接更新图表数据
   * 每次接收到数据立即处理和更新，保持与WebSocket接收频率同步
   * @param newData 新接收的实时数据
   */
  const updateChartData = (newData: RealtimeData) => {
    const maxDataLength = CHART_CONFIG.MAX_DATA_LENGTH;
    const removeCount = newData.X?.length || 0;

    // 数据验证
    if (!newData || removeCount === 0) {
      console.warn('接收到无效的图表数据');
      return;
    }

    // 转换X轴数据为字符串格式
    const processedNewData = {
      ...newData,
      X: newData.X.map(item => String(item))
    };

    // 验证数据完整性（主要数据字段）
    const requiredFields = ['X', 'X1', 'X2', 'Y1', 'Y2'];
    const isDataValid = requiredFields.every(field => {
      const fieldData = processedNewData[field as keyof RealtimeData];
      return Array.isArray(fieldData) && fieldData.length === removeCount;
    });

    if (!isDataValid) {
      console.warn('传入数据字段长度不一致，跳过更新');
      return;
    }

    /**
     * 通用数组更新函数
     * 实现滑动窗口效果，当数据超过最大长度时移除旧数据
     * 对数值数据进行范围过滤
     */
    const updateArray = <T>(existing: T[], newArr: T[], min?: number, max?: number): T[] => {
      if (!Array.isArray(existing) || !Array.isArray(newArr)) {
        return newArr;
      }

      // 如果提供了范围参数，对数值数据进行过滤
      let processedNewArr = newArr;
      if (typeof min === 'number' && typeof max === 'number') {
        processedNewArr = processDataRange(newArr as number[], min, max) as T[];
      }

      const combined = [...existing, ...processedNewArr];

      // 如果超过最大长度，移除最旧的数据
      if (combined.length > maxDataLength) {
        return combined.slice(combined.length - maxDataLength);
      }

      return combined;
    };

    // 定义各通道的数据范围
    const dataRanges = {
      X1: { min: -600, max: 600 },      // 拉出值工支
      X2: { min: -600, max: 600 },      // 拉出值非支
      Y1: { min: 5000, max: 6600 },     // 导高1
      Y2: { min: 5000, max: 6600 },     // 导高2
      SpeedList: { min: 0, max: 200 },  // 速度
      MoHaoList1: { min: 0, max: 20 },  // 磨耗1
      MoHaoList2: { min: 0, max: 20 },  // 磨耗2
      fVot: { min: 25, max: 30 },       // 网压
      fPressList1: { min: 0, max: 300 }, // 接触力1
      fPressList2: { min: 0, max: 300 }, // 接触力2
      fVibrationList1: { min: 0, max: 50 }, // 加速度1
      fVibrationList2: { min: 0, max: 50 }  // 加速度2
    };

    // 直接更新所有数据字段，应用范围过滤，立即生效
    chartData.value = {
      X: updateArray(chartData.value.X, processedNewData.X),
      X1: updateArray(chartData.value.X1, processedNewData.X1, dataRanges.X1.min, dataRanges.X1.max),
      X2: updateArray(chartData.value.X2, processedNewData.X2, dataRanges.X2.min, dataRanges.X2.max),
      Y1: updateArray(chartData.value.Y1, processedNewData.Y1, dataRanges.Y1.min, dataRanges.Y1.max),
      Y2: updateArray(chartData.value.Y2, processedNewData.Y2, dataRanges.Y2.min, dataRanges.Y2.max),
      SpeedList: updateArray(chartData.value.SpeedList, processedNewData.SpeedList || [], dataRanges.SpeedList.min, dataRanges.SpeedList.max),
      MoHaoList1: updateArray(chartData.value.MoHaoList1, processedNewData.MoHaoList1 || [], dataRanges.MoHaoList1.min, dataRanges.MoHaoList1.max),
      MoHaoList2: updateArray(chartData.value.MoHaoList2 || [], processedNewData.MoHaoList2 || [], dataRanges.MoHaoList2.min, dataRanges.MoHaoList2.max),
      WearList: updateArray(chartData.value.WearList || [], processedNewData.WearList || []),
      fVot: updateArray(chartData.value.fVot || [], processedNewData.fVot || [], dataRanges.fVot.min, dataRanges.fVot.max),
      fPressList1: updateArray(chartData.value.fPressList1 || [], processedNewData.fPressList1 || [], dataRanges.fPressList1.min, dataRanges.fPressList1.max),
      fPressList2: updateArray(chartData.value.fPressList2 || [], processedNewData.fPressList2 || [], dataRanges.fPressList2.min, dataRanges.fPressList2.max),
      fVibrationList1: updateArray(chartData.value.fVibrationList1 || [], processedNewData.fVibrationList1 || [], dataRanges.fVibrationList1.min, dataRanges.fVibrationList1.max),
      fVibrationList2: updateArray(chartData.value.fVibrationList2 || [], processedNewData.fVibrationList2 || [], dataRanges.fVibrationList2.min, dataRanges.fVibrationList2.max),
      SupportList: processedNewData.SupportList,
      SuspensionList: processedNewData.SuspensionList
    };
  };

  // 组件卸载时自动断开所有连接
  onUnmounted(() => {
    disconnectWebSockets();
  });

  return {
    isConnected,
    connectionStatus,
    chartData,
    alarmData,
    positionData,
    connectWebSockets,
    disconnectWebSockets,
    reconnectSingleSocket
  };
}